package org.egrit;

import java.awt.Point;
import java.util.concurrent.CopyOnWriteArrayList;

import org.egrit.util.Args;

/**
 * Base class providing common getter methods for immutable fields plus
 * listener management.
 *
 * @author michael
 */
public abstract class AbstractGrid implements IGrid {
    
    protected final IGridBounds bounds;
    protected final CopyOnWriteArrayList<IGridListener> listeners = new CopyOnWriteArrayList<IGridListener>();
    protected final Number outsideValue;

    public AbstractGrid(IGridBounds bounds, Number outsideValue) {
        this.bounds = bounds;
        this.outsideValue = outsideValue;
    }

    @Override
    public void addListener(IGridListener listener) {
        Args.notNull("listener", listener);
        listeners.addIfAbsent(listener);
    }

    @Override
    public IGridBounds getGridBounds() {
        return GridBoundsFactory.create(bounds);
    }

    @Override
    public abstract Number getGridValue(int gridX, int gridY);

    @Override
    public abstract Number getGridValue(Point gridPos);

    @Override
    public int getHeight() {
        return bounds.getHeight();
    }

    @Override
    public Number getOutsideValue() {
        return outsideValue;
    }

    @Override
    public int getWidth() {
        return bounds.getWidth();
    }

    @Override
    public boolean isWithin(int gridX, int gridY) {
        return bounds.containsCell(gridX, gridY);
    }

    @Override
    public void removeAllListeners() {
        listeners.clear();
    }

    @Override
    public void removeListener(IGridListener listener) {
        Args.notNull("listener", listener);
        listeners.remove(listener);
    }
    
    /**
     * {@inheritDoc}
     * <p>
     * Implemented as an empty method in this class.
     */
    @Override
    public void lock() {
        // does nothing
    }

    /**
     * {@inheritDoc}
     * <p>
     * Implemented as an empty method in this class.
     */
    @Override
    public void unlock() {
        // does nothing
    }
    
}
